﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Station.Inspect.SuaModel
{
    public class ModelScaledShape
    {
        HTuple hv_ModelID = null;

        public bool IsLoaded { get => hv_ModelID != null; }
        public void Clear()
        {
            hv_ModelID = null;
        }
        public void Load(Bitmap img)
        {
            Clear();
            try
            {
                HTuple hv_Width = null, hv_Height = null;
                HTuple hv_Num = null, hv_Area = null, hv_Row = null, hv_Column = null;
                HObject ho_Image, ho_GrayImage, ho_MedianImage, ho_Region, ho_ConnectedRegions, ho_SelectedRegions, ho_BinImage;
                HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                HOperatorSet.GenEmptyObj(out ho_GrayImage);
                ho_GrayImage.Dispose();
                HOperatorSet.GenEmptyObj(out ho_MedianImage);
                ho_MedianImage.Dispose();
                HOperatorSet.GenEmptyObj(out ho_Region);
                ho_Region.Dispose();
                HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
                ho_ConnectedRegions.Dispose();
                HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
                ho_SelectedRegions.Dispose();
                HOperatorSet.GenEmptyObj(out ho_BinImage);
                ho_BinImage.Dispose();

                ho_Image = ModelHNcc.BmpToHob_Color(img);
                //HOperatorSet.ReadImage(out ho_Image, fileName);
                hv_ModelID = new HTuple();
                hv_ModelID.Dispose();
                HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
                HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);
                //

                HOperatorSet.Threshold(ho_GrayImage, out ho_Region, 128, 255);

                //将提取的整个区域中不相连的部分分割成独立的区域

                HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);
                //获取不相连的区域的数量
                HOperatorSet.CountObj(ho_ConnectedRegions, out hv_Num);
                HOperatorSet.AreaCenter(ho_ConnectedRegions, out hv_Area, out hv_Row, out hv_Column);

                HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area",
                    "and", 700, 10000);
                HOperatorSet.RegionToBin(ho_SelectedRegions, out ho_BinImage, 255, 0, hv_Width,
      hv_Height);

                //HOperatorSet.MedianImage(ho_GrayImage, out ho_MedianImage, "circle", 5, "mirrored");
                HOperatorSet.CreateScaledShapeModel(ho_BinImage, "auto", -0.1745, 0.349, "auto", 0.9, 1.1, "auto", "auto", "use_polarity", "auto", "auto", out hv_ModelID);
                ho_Image.Dispose();
                ho_GrayImage.Dispose();
            }
            catch (Exception ex)
            {
                hv_ModelID = null;
                MessageBox.Show($"模型创建失败，{ex.Message}");
            }
        }

        public List<PointL> Find(Bitmap img, double threshold = 0.5, int num = 1)
        {
            var lst = new List<PointL>();
            try
            {
                if (hv_ModelID == null)
                    return lst;
                HObject ho_Image = ModelHNcc.BmpToHob_Color(img);
                if (ho_Image == null)
                    return lst;
                //HOperatorSet.WriteImage(ho_Image, "png", 0, "D:\\12.png");
                HTuple hv_Width = null, hv_Height = null;
                HTuple hv_Num = null, hv_Area = null, hv_Row = null, hv_Column = null;
                HTuple hv_Angle, hv_Score, hv_Scaled;
                HObject ho_GrayImage, ho_MedianImage, ho_Region, ho_ConnectedRegions, ho_SelectedRegions, ho_BinImage;
                HOperatorSet.GenEmptyObj(out ho_GrayImage);
                ho_GrayImage.Dispose();
                HOperatorSet.GenEmptyObj(out ho_MedianImage);
                ho_MedianImage.Dispose();
                //
                HOperatorSet.GenEmptyObj(out ho_Region);
                ho_Region.Dispose();
                HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
                ho_ConnectedRegions.Dispose();
                HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
                ho_SelectedRegions.Dispose();
                HOperatorSet.GenEmptyObj(out ho_BinImage);
                ho_BinImage.Dispose();


                HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
                HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);
                //

                HOperatorSet.Threshold(ho_GrayImage, out ho_Region, 128, 255);

                //将提取的整个区域中不相连的部分分割成独立的区域

                HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);
                //获取不相连的区域的数量
                HOperatorSet.CountObj(ho_ConnectedRegions, out hv_Num);
                HOperatorSet.AreaCenter(ho_ConnectedRegions, out hv_Area, out hv_Row, out hv_Column);

                HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area",
                    "and", 700, 10000);
                HOperatorSet.RegionToBin(ho_SelectedRegions, out ho_BinImage, 255, 0, hv_Width,
      hv_Height);
                //HOperatorSet.MedianImage(ho_GrayImage, out ho_MedianImage, "circle", 5, "mirrored");
                HOperatorSet.FindScaledShapeModel(ho_BinImage, hv_ModelID, -0.1745, 0.349, 0.9, 1.1, threshold, num, 0.95, "least_squares", 0, 0.9, out hv_Row, out hv_Column, out hv_Angle, out hv_Score, out hv_Scaled);
                if (hv_Angle.Length > 0)
                {
                    var cols = hv_Column.DArr;
                    var rows = hv_Row.DArr;
                    var angles = hv_Angle.DArr;
                    for (int i = 0; i < angles.Length; i++)
                    {
                        lst.Add(new PointL((float)(cols[i]), (float)(rows[i]), (float)angles[i]));
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return lst;
        }

    }
}
